import os
import logging
import subprocess
import cv2
from scenedetect import VideoManager, SceneManager, ContentDetector
import argparse
import glob
from typing import List, Tuple

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

# ================== GPU 编码器检测 ==================

def detect_gpu_support():
    """
    检测系统是否支持 GPU 加速（NVIDIA/AMD/Intel）
    """
    try:
        # 检查FFmpeg版本
        version_result = subprocess.run(
            ["ffmpeg", "-version"], capture_output=True, text=True, check=True
        )
        logging.info(f"FFmpeg版本信息: {version_result.stdout.splitlines()[0]}")

        result = subprocess.run(
            ["ffmpeg", "-encoders"], capture_output=True, text=True, check=True
        )
        if "nvenc" in result.stdout:
            return "h264_nvenc"
        if "qsv" in result.stdout:
            return "h264_qsv"
        if "amf" in result.stdout:
            return "h264_amf"
        return None
    except Exception as e:
        logging.warning(f"检测 GPU 支持失败: {e}")
        return None

# ================== 视频分割函数 ==================

def split_video_opencv(video_path: str, scene_list: List[Tuple], output_dir: str):
    """
    使用OpenCV分割视频
    """
    logging.info("使用OpenCV分割视频...")

    # 打开视频文件
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        raise Exception(f"无法打开视频文件: {video_path}")

    # 获取视频属性
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

    video_name = os.path.splitext(os.path.basename(video_path))[0]

    # 分割每个场景
    for i, (start_time, end_time) in enumerate(scene_list):
        # 计算帧数
        start_frame = int(start_time.get_seconds() * fps)
        end_frame = int(end_time.get_seconds() * fps)

        # 设置视频读取位置
        cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)

        # 创建输出文件
        output_filename = f"{video_name}-Scene-{i+1:03d}.mp4"
        output_path = os.path.join(output_dir, output_filename)

        # 创建视频写入器
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))

        # 写入帧
        frame_count = 0
        for frame_idx in range(start_frame, end_frame):
            ret, frame = cap.read()
            if not ret:
                break
            out.write(frame)
            frame_count += 1

        # 释放写入器
        out.release()
        logging.info(f"已保存场景 {i+1}: {output_path} ({frame_count} 帧)")

    # 释放视频捕获
    cap.release()
    logging.info(f"已成功使用OpenCV分割视频到目录: {output_dir}")

# ================== 视频处理核心函数 ==================

def process_video(
        video_path: str,
        output_dir: str,
        threshold: int = 25,
        min_scene_len: float = 1.0,
        use_gpu: bool = False
):
    """
    处理单个视频文件，检测场景并分割
    """
    logging.info(f"开始处理视频: {video_path}")

    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)

    video_manager = None
    try:
        # 初始化视频管理器和场景管理器
        video_manager = VideoManager([video_path])
        scene_manager = SceneManager()

        # 启动视频管理器
        video_manager.set_downscale_factor(1)  # 不降低分辨率
        video_manager.start()

        # 获取视频帧率
        framerate = video_manager.get_framerate()
        logging.info(f"视频帧率: {framerate} FPS")

        # 计算最小场景帧数
        min_scene_frames = int(min_scene_len * framerate)

        # 配置场景检测器
        scene_manager.add_detector(
            ContentDetector(threshold=threshold, min_scene_len=min_scene_frames))

        # 检测场景
        video_manager.seek(0)  # 重置到视频开头
        scene_manager.detect_scenes(frame_source=video_manager)
        scene_list = scene_manager.get_scene_list()
        logging.info(f"检测到 {len(scene_list)} 个场景。")

        # 使用OpenCV分割视频
        try:
            split_video_opencv(video_path, scene_list, output_dir)
        except Exception as e:
            logging.error(f"OpenCV分割失败: {e}")
            raise

    except Exception as e:
        logging.error(f"视频处理失败: {e}")
        raise
    finally:
        if video_manager:
            video_manager.release()

# ================== 命令行接口 ==================

def parse_args():
    parser = argparse.ArgumentParser(description="短视频自动分割工具（支持 GPU 加速）")
    parser.add_argument("video_path", help="输入视频文件或通配符（如 *.mp4）")
    parser.add_argument("--output", "-o", default="./output", help="输出目录")
    parser.add_argument("--threshold", "-t", type=int, default=25, help="场景变化阈值")
    parser.add_argument("--min-scene", "-m", type=float, default=1.0, help="最小场景时长（秒）")
    parser.add_argument("--gpu", action="store_true", help="启用 GPU 加速（需要 FFmpeg 支持）")
    return parser.parse_args()

# ================== 入口 ==================

if __name__ == "__main__":
    args = parse_args()

    # 处理通配符路径
    video_files = glob.glob(args.video_path)

    if not video_files:
        logging.error(f"未找到匹配的视频文件: {args.video_path}")
        exit(1)

    for video_file in video_files:
        # 为每个视频创建单独的输出目录
        video_name = os.path.splitext(os.path.basename(video_file))[0]
        output_dir = os.path.join(args.output, video_name)

        try:
            process_video(
                video_path=video_file,
                output_dir=output_dir,
                threshold=args.threshold,
                min_scene_len=args.min_scene,
                use_gpu=args.gpu
            )
        except Exception as e:
            logging.error(f"处理视频 {video_file} 时出错: {e}")
            continue
